<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>[3.9]-扩展类库：swoole支持下的长链接和异步任务实现 | PhalApi(π框架) - PHP轻量级开源接口框架 - 助你创造价值！</title>
    <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
    <meta content="yes" name="apple-mobile-web-app-capable">
    <meta content="black" name="apple-mobile-web-app-status-bar-style">
    <meta content="telephone=no" name="format-detection">
    <meta content="email=no" name="format-detection">
    <meta name="Author" content="PhalApi,ecitlm,dogstar">
    <meta name="description" content="[3.9]-扩展类库：swoole支持下的长链接和异步任务实现，PhalApi是一个PHP轻量级开源接口框架，致力于快速开发接口服务。支持HTTP/SOAP/RPC等协议，可用于搭建接口/微服务/RESTful接口/Web Services。我们不断更新，保持生气；为接口负责，为开源负责！并承诺永久免费！">
    <meta name="keywords" content="PhalApi,phalapi,phalapi接口开发,后台接口开发,后台接口开发框架,接口开发,接口框架,开源接口框架,PHP后台接口开发,PHP接口开发,PHP接口框架,PHP后台接口框架,phalapi官网,PHP接口框架,php接口开发框架,php接口开发,php web框架,π框架,π开发框架,π接口框架,π接口开发框架,api接口,php接口,,PHP接口框架,phalapi文档,phalapi wiki,PhalApi文档,phalapi在线文档,phalapi官方文档">

    <link rel="stylesheet" type="text/css" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" media="screen">
    <link rel="stylesheet" type="text/css" href="https://cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.css" media="screen">
    <link rel="stylesheet" href="../css/main.css" />
    <link rel="stylesheet" href="../css/loading_bar.css" />
    <link rel="icon" href="http://webtools.qiniudn.com/dog_catch.png" type="image/x-icon" />
    <script src="../js/pace.min.js"></script>
	
	<!-- 代码高亮 -->
	<link rel="stylesheet" href="../css/highlight.min.css">
	<script src="../js/highlight.min.js"></script>
	<script>hljs.initHighlightingOnLoad();</script>
    
</head>

<body>
    <!-- navbar start -->
    <div class="navbar navbar-default navbar-fixed-top" id="mainnav" role="navigation">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="sr-only">Toggle navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a class="navbar-brand website_name" href="/"><!-- <span>PhalApi</span> --><strong></strong></a>
            </div>
            <div class="navbar-collapse collapse" aria-expanded="false" style="height: 1px;">
                <ul class="nav navbar-nav navbar-right" id="nav_bar">
                    <li><a href="https://www.phalapi.net/"><span class="glyphicon glyphicon-home"></span></a></li>
                    <li><a href="https://www.phalapi.net/download.html">下载</a></li>
                    <li class="active"><a href="https://www.phalapi.net/wikis/">文档</a></li>
                    <li><a href="https://www.phalapi.net/donate.html">贡献</a></li>
                    <li><a href="#">|</a></li>
                    <li><a href="http://qa.phalapi.net/" target="_blank">社区</a></li>
                    <li><a href="http://www.ituring.com.cn/book/2405" target="_blank">书籍</a></li>
                    <li><a href="http://demo.phalapi.net/listAllApis.php" target="_blank">体验</a></li>
                    <li><a href="https://github.com/phalapi/phalapi-library" target="_blank">扩展</a></li>
                </ul>
            </div>
            <!--/.nav-collapse -->
        </div>
    </div>
    <!-- navbar end -->


    <div id="content">
        <div class="container">
            <div class="row row-md-flex row-md-flex-wrap">
                <h4><a href="/wikis/%5B3.8%5D-%E6%89%A9%E5%B1%95%E7%B1%BB%E5%BA%93%EF%BC%9A%E7%94%A8%E6%88%B7%E3%80%81%E4%BC%9A%E8%AF%9D%E5%92%8C%E7%AC%AC%E4%B8%89%E6%96%B9%E7%99%BB%E5%BD%95%E9%9B%86%E6%88%90.html">上一章</a>   <a href="/wikis/">文档首页</a>   <a href="#">下一章</a></h4>
<hr />
<p><em>遵守规则可以让你远离选择烦恼，无论是在坐车还是参加鸡尾酒会的时候。 --《选择的悖论》</em>  </p>
<h2>写在前面的话</h2>
<p>此PhalApi扩展类库只是初步开发完成，建议有swoole扩展经验或非保守派的同学使用，也欢迎你来丰富完善此扩展类库。</p>
<h2>3.9.1 扩展类库：swoole支持下的长链接和异步任务实现</h2>
<p>swoole官网请见： <a href="http://www.swoole.com/">Swoole: PHP的异步、并行、分布式扩展</a>  </p>
<p>在这里，首先需要非常感谢swoole。  </p>
<p>因为Swoole给我们提供了很多解决以往因PHP本身限制而产生的难题的灵感，但与此同时，也给我们带来了从没遇到过的挑战，特别是并发和长时间运行。  </p>
<p>这需要我们更为小心地进行编码，因为以往可以忽略的小问题，在新的解决方案背景下都可能成为一个大问题。此扩展类库更多是作为一种尝试，并且可以作为扩展类库重要的一个转换点。因为在今后的日子里， <strong>PhalApi将会争取与其他开源项目一起，提供企业级的解决方案</strong> 。  </p>
<p>目前，此扩展类库提供了：</p>
<ul>
<li>长链接的接口调用</li>
<li>异步计划任务的调用</li>
</ul>
<h2>3.9.2 安装</h2>
<p>(1)安装swoole扩展类库
安装过程可以参考swoole官网，这里稍以linux系统简单说明一下编译安装。</p>
<pre><code class="language-bash">unzip ./swoole-src-swoole-1.7.16-beta.zip
cd swoole-src-swoole-1.7.16-beta
phpize
./configure
make &amp;&amp; make install</code></pre>
<p>安装好后，添加swoole扩展：</p>
<pre><code>extension=swoole.so</code></pre>
<p>重启PHP后，如果看到有swoole扩展，则说明安装成功：</p>
<pre><code class="language-bash">#php -m | grep swoole
swoole</code></pre>
<h3>(2)扩展包下载</h3>
<p>从  <a href="http://git.oschina.net/dogstar/PhalApi-Library">PhalApi-Library</a>  扩展库中下载获取 <strong>Swoole</strong> 包，如使用：</p>
<pre><code class="language-bash">$ git clone https://git.oschina.net/dogstar/PhalApi-Library.git</code></pre>
<p>然后把 <strong>Swoole</strong> 目录复制到 <strong>./PhalApi/Library/</strong> 下，即：</p>
<pre><code class="language-bash">$ cp ./PhalApi-Library/Swoole/ ./PhalApi/Library/ -R</code></pre>
<p>到此安装完毕！ </p>
<blockquote>
<p>温馨提示：<br />
此扩展类库需要PhaApi 1.1.4及以上版本。</p>
</blockquote>
<h3>(3)配置</h3>
<p>将以下配置追加到./Config/app.php：</p>
<pre><code class="language-php">    /**
     * Swoole扩展类库
     */
    'Swoole' =&gt; array(
        //服务
        'server' =&gt; array(
            'ip' =&gt; '127.0.0.1',
            'port' =&gt; 9501,
            'worker_num' =&gt; 1,
        ),
        //计划任务
        'task' =&gt; array(
            'ip' =&gt; '127.0.0.1',
            'port' =&gt; 9502,
            'worker_num' =&gt; 1,
        ),
    ),</code></pre>
<h2>3.9.3 入门使用</h2>
<h3>(1)长链接入口</h3>
<p>在使用长链接入口对外提供接口服务后，由于不再是HTTP协议，所以入口建议放置在新的目录./Server，而不再是./Public。<br />
入口文件的编写，如同我们以往一样，很简单：</p>
<pre><code class="language-php">//$ vim ./Server/run_server.php
&lt;?php

require_once dirname(__FILE__) . '/../Public/init.php';

DI()-&gt;loader-&gt;addDirs(array('Library', 'Demo'));

$swooleLite = new Swoole_Lite();
$swooleLite-&gt;runServer();
</code></pre>
<h4>启动、重启和关闭服务</h4>
<p>启动可以用：</p>
<pre><code class="language-php">php ./Server/run_server.php</code></pre>
<p>关闭可以用：</p>
<pre><code class="language-php">ps -ef | grep run_server | grep -v grep | awk '{print $2}'|xargs kill -9</code></pre>
<h3>(2)异步计划任务</h3>
<p>异步计划任务是新型的做法，即：也通过接口服务调用的方式来完成计划任务的调度，其启动文件如同长链接入口一样简单：</p>
<pre><code class="language-php">//$ vim ./Server/run_task.php
&lt;?php

require_once dirname(__FILE__) . '/../Public/init.php';

DI()-&gt;loader-&gt;addDirs(array('Library', 'Demo'));

$swooleLite = new Swoole_Lite();
$swooleLite-&gt;runTask();</code></pre>
<h4>启动、重启和关闭服务</h4>
<p>启动可以用：</p>
<pre><code class="language-php">nohup php ./Server/run_task.php &gt; ./Server/run_task.log 2&gt;&amp;1 &amp;</code></pre>
<h3>(3)客户端调用</h3>
<p>在扩展类库里有一个测试的脚本，可以用来进行PHP客户端的请求。</p>
<h4>(1)默认接口调用</h4>
<pre><code class="language-bash">$ php ./check.php 127.0.0.1 9501 Default.Index username=swoole
Send: {"service":"Default.Index","username":"swoole"}
Received: {"ret":200,"data":{"title":"Hello World!","content":"Hi swoole, welcome to use PhalApi!","version":"1.1.3","time":1430620911},"msg":""}
Connection close</code></pre>
<h4>(2)带数据库的调用</h4>
<pre><code class="language-bash">$ php ./check.php 127.0.0.1 9501 User.getBaseInfo userId=1
Send: {"service":"User.getBaseInfo","userId":"1"}
Received: {"ret":200,"data":{"code":0,"msg":"","info":{"id":"1","username":"aevit","nickname":"test","password":"DE4CA99150F44B26F0D320DCA6E4B7629C43B6","salt":"wefewfew","reg_time":"0","avatar":"http:\/\/image.famillelab.com\/no_avatar.png","UUID":""}},"msg":""}
Connection close</code></pre>
<h4>(3)异步计划任务的调度</h4>
<pre><code class="language-bash">$ php ./check.php 127.0.0.1 9502 Default.Index username=swoole
Send: {"service":"Default.Index","username":"swoole"}
Connection close</code></pre>
<p>假设Default.Index为一个计划任务的接口，但目前发现一个问题是，首次请求异步计划任务不会主动结束，而需要工作强制ctrl + c结束，再请求，则正常。  </p>
<p>对应的log，可以看到：</p>
<pre><code class="language-bash">2015-05-03 12:24:57|DEBUG|asynctask(0) dispath in swoole|{"service":"Default.Index","username":"swoole"}
2015-05-03 12:24:57|DEBUG|asynctask(0) start in swoole|{"service":"Default.Index","username":"swoole"}
2015-05-03 12:24:57|DEBUG|asynctask(0) finish in swoole|{"ret":200,"data":{"title":"Hello World!","content":"Hi swoole, welcome to use PhalApi!","version":"1.1.3","time":1430627097},"msg":""}
2015-05-03 12:24:57|DEBUG|asynctask(1) dispath in swoole|{"service":"Default.Index","username":"swoole"}
2015-05-03 12:24:57|DEBUG|asynctask(1) start in swoole|{"service":"Default.Index","username":"swoole"}
2015-05-03 12:24:57|DEBUG|asynctask(1) finish in swoole|{"ret":200,"data":{"title":"Hello World!","content":"Hi swoole, welcome to use PhalApi!","version":"1.1.3","time":1430627097},"msg":""}
...</code></pre>
<h2>3.9.4 对客户端调整</h2>
<h3>(1)调用方式的改变</h3>
<p>改用长链接。</p>
<h3>(2)POST参数传递方式的改变</h3>
<p>统一使用json发送数据包。</p>
<h2>3.9.5 对服务端的影响</h2>
<h3>(1)DI资源服务的调整</h3>
<table class="table table-bordered">
<thead>
<tr>
<th>变量名称</th>
<th>是否全局通用</th>
<th>是否每次请求新建</th>
<th>可否使用</th>
<th>备注</th>
</tr>
</thead>
<tbody>
<tr>
<td>loader</td>
<td>是</td>
<td>否</td>
<td>可使用</td>
</tr>
<tr>
<td>config</td>
<td>是</td>
<td>否</td>
<td>可使用</td>
</tr>
<tr>
<td>logger</td>
<td>是</td>
<td>否</td>
<td>可使用</td>
</tr>
<tr>
<td>notorm</td>
<td>是</td>
<td>否</td>
<td>可使用</td>
<td>每次响应后，关闭此次全部数据库链接</td>
</tr>
<tr>
<td>cache</td>
<td>是</td>
<td>否</td>
<td>可使用</td>
<td>需要查看使用的链接是否支持长链接</td>
</tr>
<tr>
<td>filter</td>
<td>是</td>
<td>否</td>
<td>可使用</td>
</tr>
<tr>
<td>crypt</td>
<td>是</td>
<td>否</td>
<td>可使用</td>
</tr>
<tr>
<td>curl</td>
<td>是</td>
<td>否</td>
<td>可使用</td>
</tr>
<tr>
<td>request</td>
<td>否</td>
<td>是</td>
<td>可使用</td>
</tr>
<tr>
<td>response</td>
<td>否</td>
<td>是</td>
<td>可使用</td>
</tr>
<tr>
<td>cookie</td>
<td>---</td>
<td>---</td>
<td>不可使用</td>
<td>长链接下不应进行COOKIE的操作</td>
</tr>
</tbody>
</table>
<h3>(2)关于swoole扩展类库的自问自答</h3>
<ul>
<li>1、数据库使用长链接吗？ -- 不使用，每次响应后手动关闭数据链接</li>
<li>2、内存问题？-- 通过类成员方法的作用域控制内存</li>
<li>3、并发的问题？-- TODO</li>
<li>4、代码更新后如何同步？需要重启服务器吗？  -- 需要重启</li>
<li>5、PhalApi_Response::formatResult()的访问权限，是框架的调整，还是个别自我提高？ -- 扩展自我提高</li>
<li>6、注册错误回调函数？ -- 来自swoole的建议，已注册</li>
<li>7、启动和关闭、重启脚本文件？ -- 提供参考命令</li>
<li>8、一直运行？ -- TODO
<h3>(3)特别注意！</h3>
<p>由于服务在启动后，已经完成了大部分的类加载、配置读取以及PHP文件的解析，所以在对项目代码（包括配置）修改后，需要重启服务，方能生效。</p></li>
</ul>
<hr />
<h4><a href="/wikis/%5B3.8%5D-%E6%89%A9%E5%B1%95%E7%B1%BB%E5%BA%93%EF%BC%9A%E7%94%A8%E6%88%B7%E3%80%81%E4%BC%9A%E8%AF%9D%E5%92%8C%E7%AC%AC%E4%B8%89%E6%96%B9%E7%99%BB%E5%BD%95%E9%9B%86%E6%88%90.html">上一章</a>   <a href="/wikis/">文档首页</a>   <a href="#">下一章</a></h4><div style="float: left">
<h4>
<a href="http://qa.phalapi.net/">还有疑问？欢迎到社区提问！</a>
&nbsp;&nbsp;
<a href="http://docs.phalapi.net/#/v2.0/">切换到PhalApi 2.x 开发文档。</a>
</h4>
</div>
            </div>
        </div>
    </div>

 <!-- 广告位 -->
<div class="grid-wrapper desktop-only">
	<p align="center">
		<a href="http://7xiz2f.com1.z0.glb.clouddn.com/%E6%88%91%E7%9A%84%E5%90%8D%E5%AD%97%E5%8F%AB%EF%BC%9A%CF%80%E6%A1%86%E6%9E%B6%20-%20PhalApi%202016%E5%B9%B4%E5%BA%A6%E5%BC%80%E6%BA%90%E6%80%BB%E7%BB%93%20-%20%E5%AE%98%E6%96%B9%E5%87%BA%E5%93%81.pdf" target="blank"><img width="950" height="100" src="http://7xiz2f.com1.z0.glb.clouddn.com/ad_20170104.png"></a>
		<a href="http://www.itran.cc/" target="blank"><img width="950" height="100" src="http://7xslqv.com1.z0.glb.clouddn.com/images/9/69/b88bc92455dc1239f9a5bf8d72929.png"></a>
		<a href="http://web-tools.phalapi.net/" target="blank"><img width="950" height="100" src="http://7xslqv.com1.z0.glb.clouddn.com/images/7/d0/88f523566c482296aecc43d185ca2.png"></a>
	</p>
</div>

        <!-- footer -->
        <div class="footer">
            <div class="link container ">
                <div class=" col-xs-7 col-sm-7 col-md-7 col-lg-7 ">
                    <h3>PhalApi (π框架)</h3>
                    <p>一个轻量级PHP开源接口框架，专注于接口服务开发，支持HTTP/SOAP/RPC协议，拥有自动生成的在线文档、多种开发语言的客户端SDK包以及可重用的扩展类库，可用于快速搭建微服务、RESTful接口或Web
                        Services。</p>
                    <!-- <p>:</p> -->
                    <a href="https://www.phalapi.net/" target="_blank"> PhalApi </a>
                    <span>|</span>
                    <a href="http://qa.phalapi.net/" target="_blank">社区</a>
                    <span>|</span>
                    <a href="download.html" target="_blank">下载</a>
                    <span>|</span>
                    <a href="/wikis/">文档</a>
                    <span>|</span>
                    <a href="http://www.ituring.com.cn/book/2405" target="_blank">书籍</a>
                    <span>|</span>
                    <a href="http://demo.phalapi.net/listAllApis.php" target="_blank">体验</a>
                    <span>|</span>
                    <a href="donate.html" target="_blank">贡献</a>
                    <span>|</span>
                    <a href="https://github.com/phalapi/phalapi-library" target="_blank">扩展</a>
                    <span>|</span>
                    <a href="/license.html" target="_blank">许可</a>
                    <span>|</span>
                    <a href="/about.html" target="_blank">关于</a>
                    <span>|</span>
                    <a href="https://www.phalapi.net/wikis/en/" target="_blank">English</a>

                </div>
                <div class=" col-xs-5 col-sm-5 col-md-5 col-lg-5 contact_us ">
                    <h3>联系我们</h3>
                    <a href="https://github.com/phalapi/phalapi"><img src="../images/github.png" alt="github" /></a>
                    <a href="http://weibo.com/p/100808d236e99beb645bfb56ed1c37dde9b8bd?k=phalapi%E5%BC%80%E6%BA%90%E6%A1%86%E6%9E%B6&from=501&_from_=huati_topic"><img src="../images/weibo.png"  alt="weibo" /></a>
                    <a href="http://7xslqv.com1.z0.glb.clouddn.com/images/1/b0/894fde762850cb11250253f7d5ede.png"><img src="../images/zfb.png"  alt="zfb" /></a>
					<a target="_blank" href="//shang.qq.com/wpa/qunwpa?idkey=f16292029e59975d4ccfccc70ed87aa5c5646df512e83b0e9e1270e8368be461"><img border="0" src="images/qq.png" alt="π框架 - PhalApi交流群②" title="π框架 - PhalApi交流群②"></a>
					<a href="http://git.oschina.net/dogstar/PhalApi"><img src="../images/git-oschina.png"  alt="git-oschina" /></a>
                </div>
                <div class="cls"></div>
                <div class="text-center copy_right"> ©2015-2017 PhalApi All Rights Reserved. <a href="http://www.miitbeian.gov.cn" target="_blank">粤ICP备15028808号</a>

				<script type="text/javascript">var cnzz_protocol = (("https:" == document.location.protocol) ? " https://" : " http://");document.write(unescape("%3Cspan id='cnzz_stat_icon_1255326144'%3E%3C/span%3E%3Cscript src='" + cnzz_protocol + "s4.cnzz.com/z_stat.php%3Fid%3D1255326144%26show%3Dpic' type='text/javascript'%3E%3C/script%3E"));</script>
                </div>
            </div>
        </div>
    </div>


    <a href="https://github.com/phalapi"><img id="gitHub_fllow" style="position: fixed; top: 0; right: 0; border: 0;z-index:9999" src="https://camo.githubusercontent.com/652c5b9acfaddf3a9c326fa6bde407b87f7be0f4/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f6f72616e67655f6666373630302e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_orange_ff7600.png"></a>


    <script src="../js/jquery-1.11.1.min.js"></script>
    <script src="../js/bootstrap.min.js"></script>
</body>

</html>